﻿using System;
using System.Collections.Generic;

using System.Windows;



namespace DailyFx.UI
{

	public abstract class Bootstrapper : IServiceLocator
	{
		/// <summary>
		///		
		/// </summary>
		private bool _isBooted;
 
		/// <summary>
		///		The application.
		/// </summary>
		protected Application Application
		{
			get;
			set;
		}

		/// <summary>
		///		
		/// </summary>
		protected Bootstrapper ()
		{
		}

		/// <summary>
		/// 
		/// </summary>
		public void Boot ( )
		{
			if ( this._isBooted )
				return;

			this._isBooted = true;

			if ( Execution.AtDesigning )
			{
				try 
				{
					BootAtDesigning ();
				}
				catch
				{
					 //if something fails at design-time, there's really nothing we can do...
                    this._isBooted = false;
                    throw;
				}
			}
			else 
			{
				BootAtRunning ();
			}
		}

		/// <summary>
        ///		Called by the bootstrapper's constructor at design time to start the framework.
        /// </summary>
        protected virtual void BootAtDesigning ()
		{
			IoC.DoGet = this.GetService;
			IoC.DoGetAll = this.GetServices;
			IoC.Build = this.EnsureService;

        }

		protected virtual void BootAtRunning ()
		{
			Application.Startup += OnStartup;
			Application.Exit += OnExit;

			IoC.DoGet = this.GetService;
			IoC.DoGetAll = this.GetServices;
			IoC.Build = this.EnsureService;
		}


		/// <summary>
		/// 
		/// </summary>
		public object GetService ( Type serviceType )
		{
			return this.GetService( serviceType, null );
		}

		/// <summary>
		///		Gets an instance of the given named <paramref name="type"/>.
		/// </summary>
		public abstract object GetService ( Type type, string key ) ;


		/// <summary>
		///		Gets all instances of the given <paramref name="type"/> currently registered .
		/// </summary>
		public abstract IEnumerable<object> GetServices ( Type type ) ;


		/// <summary>
		///		performs injection on the specified instance .
		/// </summary>
		protected virtual void EnsureService ( object instance ) 
		{ // 
		}

		/// <summary>
		///		Adds custom behavior to execute after the application starts.
		/// </summary>
		protected virtual void OnStartup ( object sender, StartupEventArgs e ) 
		{
			var windowManager = IoC.Get<IWindowManager> ();
			windowManager.ShowWindow ( IoC.Get<IMainWindow>(null), null, null );
		}

		/// <summary>
        ///		Adds custom behavior on exit.
        /// </summary>
        protected virtual void OnExit ( object sender, EventArgs e) 
		{ 
		}

	}

	  
}
